package epidemic

import (
	"errors"
	"gitee.com/baal1990/epidemic/global"
	"gitee.com/baal1990/epidemic/model/epidemic"
	request2 "gitee.com/baal1990/epidemic/model/epidemic/request"
	"gitee.com/baal1990/epidemic/utils/prepare"
	"github.com/xuri/excelize/v2"
	"go.uber.org/zap"
	"strconv"
	"strings"
	"time"
)

type EpidemicRelatedStaffHistoryService struct {
}

func (e EpidemicRelatedStaffHistoryService) List(page request2.EpidemicRelatedStaffHistorySearch, user epidemic.EpidemicUser) (list []epidemic.EpidemicRelatedStaffHistory, total int64, err error) {
	limit := page.PageSize
	offset := page.PageSize * (page.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&epidemic.EpidemicRelatedStaffHistory{})
	db = db.Table("epidemic_related_staff_history")
	if user.Role != global.DICT_ROLES_SUPER {
		db = db.Where("company=? and department in ?", user.Company, prepare.Department(user.Department))
	}
	// 如果有条件搜索 下方会自动创建搜索语句
	if len(page.Name) > 0 {
		db = db.Where("name like ?", "%"+page.Name+"%")
	}
	if len(page.Company) > 0 {
		db = db.Where("company = ?", page.Company)
	}
	if len(page.Department) > 0 {
		db = db.Where("department = ?", page.Department)
	}
	if len(page.Organization) > 0 {
		db = db.Where("organization = ?", page.Organization)
	}
	if len(page.Location) > 0 {
		db = db.Where("location = ?", page.Location)
	}
	if len(page.IsolationType) > 0 {
		db = db.Where("isolation_type = ?", page.IsolationType)
	}
	if len(page.HomeBeginDateStart) > 0 && len(page.HomeBeginDateEnd) > 0 {
		db = db.Where("home_begin_date >= ? and home_begin_date <= ?", page.HomeBeginDateStart, page.HomeBeginDateEnd)
	}
	if len(page.CompanyOaDateStart) > 0 && len(page.CompanyOaDateEnd) > 0 {
		db = db.Where("company_oa_date >= ? and company_oa_date <= ?", page.CompanyOaDateStart, page.CompanyOaDateEnd)
	}
	if len(page.ReturnDateStart) > 0 && len(page.ReturnDateEnd) > 0 {
		db = db.Where("return_date >= ? and return_date <= ?", page.ReturnDateStart, page.ReturnDateEnd)
	}
	var epidemicRelatedStaffs []epidemic.EpidemicRelatedStaffHistory
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	if err = db.Limit(limit).
		Offset(offset).
		Order("id desc").
		Find(&epidemicRelatedStaffs).Error; err != nil {
		global.GVA_LOG.Error("加密失败!", zap.Error(err))
		return
	}
	for i := 0; i < len(epidemicRelatedStaffs); i++ {
		epidemicRelatedStaffs[i].Name, err = global.AsymmetricCrypto.EncryptWithPrvKOutputBase64([]byte(epidemicRelatedStaffs[i].Name))
		if err != nil {
			global.GVA_LOG.Error("加密失败!", zap.Error(err))
		}
		epidemicRelatedStaffs[i].Details, err = global.AsymmetricCrypto.EncryptWithPrvKOutputBase64([]byte(epidemicRelatedStaffs[i].Details))
		if err != nil {
			global.GVA_LOG.Error("加密失败!", zap.Error(err))
		}
	}
	return epidemicRelatedStaffs, total, err
}

// Export 导出全部
func (e EpidemicRelatedStaffHistoryService) Export(user epidemic.EpidemicUser) (filename string, err error) {
	// 创建db
	db := global.GVA_DB.Model(&epidemic.EpidemicRelatedStaffHistory{})
	// 获取信息
	if user.Role != global.DICT_ROLES_SUPER {
		db = db.Where("department in ? and company=?", prepare.Department(user.Department), user.Company)
	} else {
		db = db.Where("company=?", user.Company)
	}
	var info []epidemic.EpidemicRelatedStaffHistory
	if err = db.Table("epidemic_related_staff_history").Find(&info).Error; err != nil {
		return
	}

	return e.GenExcel(info)
}

// GenExcel 生成excel
func (h EpidemicRelatedStaffHistoryService) GenExcel(info []epidemic.EpidemicRelatedStaffHistory) (string, error) {
	f := excelize.NewFile()
	// Create a new sheet.
	sheet := "Sheet1"
	index := f.NewSheet(sheet)
	// Set value of a cell.
	if err := h.genExcelTittle(f, sheet); err != nil {
		return "", err
	}
	for i, e := range info {
		line := i + 2
		id := i + 1
		if err := h.genExcelLine(e, f, sheet, id, line); err != nil {
			return "", err
		}
	}
	// Set active sheet of the workbook.
	f.SetActiveSheet(index)
	// Save spreadsheet by the given path.
	nowDate := time.Now().Format("2006-01-02")
	fileName := global.GVA_CONFIG.System.ExportFileDir + "居家记录" + nowDate + ".xlsx"
	if err := f.SaveAs(fileName); err != nil {
		return "", err
	}
	return fileName, nil
}

// 生成标头
func (e EpidemicRelatedStaffHistoryService) genExcelTittle(f *excelize.File, sheet string) error {
	var Tittle = []string{
		"总序号",
		"姓名",
		"公司",
		"部门",
		"具体情况",
		"居家日期",
		"返岗日期",
	}
	for i := 0; i < len(Tittle); i++ {
		axis := string(rune(65 + i))
		value := Tittle[i]
		if err := f.SetCellValue(sheet, axis+strconv.Itoa(1), value); err != nil {
			return err
		}
	}
	return nil
}

func (e EpidemicRelatedStaffHistoryService) genExcelLine(info epidemic.EpidemicRelatedStaffHistory, f *excelize.File, sheet string, id, line int) error {
	i := 0
	if err := setCellValue(f, &i, id, sheet, line); err != nil {
		return err
	}
	if err := setCellValue(f, &i, info.Name, sheet, line); err != nil {
		return err
	}
	Company, _ := GetNameByKeyAndValue("company", info.Company)
	if err := setCellValue(f, &i, Company, sheet, line); err != nil {
		return err
	}
	departmentSlice := strings.Split(info.Department, ",")
	Department := ""
	for i, e := range departmentSlice {
		tmp, _ := GetNameByKeyAndValue("department", e)
		Department += tmp
		if i+1 != len(departmentSlice) {
			Department += ","
		}
	}
	if err := setCellValue(f, &i, Department, sheet, line); err != nil {
		return err
	}

	if err := setCellValue(f, &i, info.Details, sheet, line); err != nil {
		return err
	}
	if info.HomeBeginDate != nil {
		if err := setCellValue(f, &i, info.HomeBeginDate.Format("2006/01/02"), sheet, line); err != nil {
			return err
		}
	} else {
		if err := setCellValue(f, &i, "", sheet, line); err != nil {
			return err
		}
	}
	if info.ReturnDate != nil {
		if err := setCellValue(f, &i, info.ReturnDate.Format("2006/01/02"), sheet, line); err != nil {
			return err
		}
	} else {
		if err := setCellValue(f, &i, "", sheet, line); err != nil {
			return err
		}
	}
	return nil
}

func (e EpidemicRelatedStaffHistoryService) SyncHistory(mobile string, mode int) {
	var info epidemic.EpidemicRelatedStaff
	var err error
	dbStaff := global.GVA_DB.Model(&epidemic.EpidemicRelatedStaff{})
	if err := dbStaff.Table("epidemic_related_staff").
		Where("mobile=?", mobile).
		First(&info).Error; err != nil {
		global.GVA_LOG.Sugar().Error("SyncHistory fail, mobile=[", mobile, "], err=[", err, "]")
		return
	}
	db := global.GVA_DB.Model(&epidemic.EpidemicRelatedStaffHistory{})
	db = db.Table("epidemic_related_staff_history")
	switch mode {
	case global.SYNC_MODE_ADD:
		tmp := "居住地址：" + info.RegionName + info.ResidentialAddress + "\r\n所属社区：" + info.Community + "\r\n社区电话：" + info.CommunityTel + "\r\n所属接到：" + info.Street
		tmp += "\r\n情况描述：" + info.Description + "\r\n社区要求：" + info.CommunityRequirements + "\r\n核酸记录："
		NucleicAcidRecord, err := marshalNucleicAcidRecord(info.NucleicAcidRecord)
		if err != nil {
			global.GVA_LOG.Sugar().Error("SyncHistory fail, mobile=[", mobile, "], mode=[", mode, "]err=[", err, "]")
			return
		}
		tmp += NucleicAcidRecord + "\r\n体温记录："
		TemperatureRecord, err := marshalTemperatureRecord(info.TemperatureRecord)
		if err != nil {
			global.GVA_LOG.Sugar().Error("SyncHistory fail, mobile=[", mobile, "], mode=[", mode, "]err=[", err, "]")
			return
		}
		tmp += TemperatureRecord
		history := epidemic.EpidemicRelatedStaffHistory{
			Mobile:        mobile,
			Name:          info.Name,
			Company:       info.Company,
			Department:    info.Department,
			Location:      info.Location,
			IsolationType: info.IsolationType,
			Details:       tmp,
			HomeBeginDate: info.HomeBeginDate,
			ReturnDate:    info.ReturnDate,
			CompanyOaDate: info.CompanyOaDate,
			CreatedAt:     time.Now(),
			RelatedId:     info.ID,
		}
		if err = db.Save(&history).Error; err != nil {
			global.GVA_LOG.Sugar().Error("SyncHistory fail, mobile=[", mobile, "], mode=[", mode, "]err=[", err, "]")
		}
	case global.SYNC_MODE_UPDATE:
		tmp := "居住地址：" + info.RegionName + info.ResidentialAddress + "\r\n所属社区：" + info.Community + "\r\n社区电话：" + info.CommunityTel + "\r\n所属接到：" + info.Street
		tmp += "\r\n情况描述：" + info.Description + "\r\n社区要求：" + info.CommunityRequirements + "\r\n核酸记录："
		NucleicAcidRecord, err := marshalNucleicAcidRecord(info.NucleicAcidRecord)
		if err != nil {
			global.GVA_LOG.Sugar().Error("SyncHistory fail, mobile=[", mobile, "], mode=[", mode, "]err=[", err, "]")
			return
		}
		tmp += NucleicAcidRecord + "\r\n体温记录："
		TemperatureRecord, err := marshalTemperatureRecord(info.TemperatureRecord)
		if err != nil {
			global.GVA_LOG.Sugar().Error("SyncHistory fail, mobile=[", mobile, "], mode=[", mode, "]err=[", err, "]")
			return
		}
		tmp += TemperatureRecord
		history := epidemic.EpidemicRelatedStaffHistory{
			Mobile:        mobile,
			Name:          info.Name,
			Company:       info.Company,
			Department:    info.Department,
			Organization:  info.Organization,
			Location:      info.Location,
			AppletReport:  info.AppletReport,
			IsolationType: info.IsolationType,
			Details:       tmp,
			HomeBeginDate: info.HomeBeginDate,
			ReturnDate:    info.ReturnDate,
			CompanyOaDate: info.CompanyOaDate,
			UpdatedAt:     time.Now(),
		}
		if err = db.Where("related_id=? ", info.ID).
			Updates(&history).Error; err != nil {
			global.GVA_LOG.Sugar().Error("SyncHistory fail, mobile=[", mobile, "], mode=[", mode, "]err=[", err, "]")
		}
	case global.SYNC_MODE_DELETE:
		if err = db.Where("related_id=? ", info.ID).
			Delete(&epidemic.EpidemicRelatedStaffHistory{}).Error; err != nil {
			global.GVA_LOG.Sugar().Error("SyncHistory fail, mobile=[", mobile, "], mode=[", mode, "]err=[", err, "]")
		}
	}
}

func (e EpidemicRelatedStaffHistoryService) SyncHistoryReturn(id int, returnDate *time.Time) (err error) {
	history := epidemic.EpidemicRelatedStaffHistory{
		ReturnDate: returnDate,
		UpdatedAt:  time.Now(),
	}
	db := global.GVA_DB.Table("epidemic_related_staff_history")
	return db.Where("related_id=? ", id).
		Updates(&history).Error
}

// Reduction 数据恢复
func (e EpidemicRelatedStaffHistoryService) Reduction(req request2.EpidemicRelatedStaffHistoryOperation) (err error) {
	// 创建db
	db := global.GVA_DB.Table("epidemic_related_staff_history")
	// 获取信息
	var info epidemic.EpidemicRelatedStaffHistory
	if err = db.Where("id=?", req.ID).
		Find(&info).Error; err != nil {
		return
	}
	if info.Name == "" {
		return errors.New("no data")
	}
	staffService := EpidemicRelatedStaffService{}
	staff := request2.EpidemicRelatedStaffSet{
		Mobile:        info.Mobile,
		Name:          info.Name,
		Company:       info.Company,
		Department:    info.Department,
		Organization:  info.Organization,
		Location:      info.Location,
		AppletReport:  info.AppletReport,
		IsolationType: info.IsolationType,
		ReportDate:    time.Now().Format("2006-01-02"),
	}
	if info.HomeBeginDate != nil {
		staff.HomeBeginDate = info.HomeBeginDate.Format("2006-01-02")
	}
	if info.ReturnDate != nil {
		staff.ReturnDate = info.ReturnDate.Format("2006-01-02")
	}
	if info.CompanyOaDate != nil {
		staff.CompanyOaDate = info.CompanyOaDate.Format("2006-01-02")
	}
	// 恢复社区信息
	content := strings.Split(info.Details, "\r\n")
	for _, e := range content {
		if strings.HasPrefix(e, "所属社区：") {
			tmp := strings.Split(e, "：")
			staff.Community = tmp[1]
		} else if strings.HasPrefix(e, "社区电话：") {
			tmp := strings.Split(e, "：")
			staff.CommunityTel = tmp[1]
		} else if strings.HasPrefix(e, "情况描述：") {
			tmp := strings.Split(e, "：")
			staff.Description = tmp[1]
		} else if strings.HasPrefix(e, "社区要求：") {
			tmp := strings.Split(e, "：")
			staff.CommunityRequirements = tmp[1]
		} else if strings.HasPrefix(e, "所属街道：") {
			tmp := strings.Split(e, "：")
			staff.Street = tmp[1]
		}
	}
	serviceUser := EpidemicUserService{}
	user, err := serviceUser.GetUserByMobile(info.Mobile)
	if err != nil {
		return
	}
	staff.Region = user.ResidentialAddressCode
	staff.RegionName = user.ResidentialAddressName
	staff.ResidentialAddress = user.ResidentialAddressDetail
	if err = staffService.SaveEpidemicRelatedStaff("", staff); err != nil {
		return
	}
	if err = e.Delete(req); err != nil {
		return
	}
	return
}

// Delete 删除
func (e EpidemicRelatedStaffHistoryService) Delete(req request2.EpidemicRelatedStaffHistoryOperation) (err error) {
	// 创建db
	db := global.GVA_DB.Table("epidemic_related_staff_history")
	// 获取信息
	return db.Where("id=?", req.ID).
		Delete(&epidemic.EpidemicRelatedStaffHistory{}).Error
}
